from machine import I2C, Pin
from ssd1306 import SSD1306_I2C
import time
import _thread

from CNfont import getfont
# 示例中文字模，需替换为完整字模
# CHINESE_FONT = {
# "你":[0x08,0x80,0x08,0x80,0x08,0x80,0x11,0xFE,0x11,0x02,0x32,0x04,0x34,0x20,0x50,0x20,0x91,0x28,0x11,0x24,0x12,0x24,0x12,0x22,0x14,0x22,0x10,0x20,0x10,0xA0,0x10,0x40],
# "好":[0x10,0x00,0x10,0xFC,0x10,0x04,0x10,0x08,0xFC,0x10,0x24,0x20,0x24,0x20,0x25,0xFE,0x24,0x20,0x48,0x20,0x28,0x20,0x10,0x20,0x28,0x20,0x44,0x20,0x84,0xA0,0x00,0x40],
# "。":[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x24,0x00,0x24,0x00,0x18,0x00,0x00,0x00,0x00,0x00],
# "一":[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
# }
def draw_chinese(oled, char, x, y):

    """在指定位置绘制一个 16x16 的中文字符"""
    if char not in getfont():
        print(f"未找到字符: {char}")
        return
    data = getfont()[char]

    for row in range(16):  # 遍历每一行
        # 左侧部分（偶数位，高字节）绘制在后
        low_byte = data[row * 2]  # 偶数位，高字节
        # 右侧部分（奇数位，低字节）绘制在前
        high_byte = data[row * 2 + 1]  # 奇数位，低字节

        for col in range(8):  # 遍历每列的每一位
            # 先绘制右侧部分（高字节），对应右侧 8 列
            if high_byte & (0x80 >> col):  
                oled.pixel(x + col + 8, y + row, 1)
            # 后绘制左侧部分（低字节），对应左侧 8 列
            if low_byte & (0x80 >> col):  
                oled.pixel(x + col, y + row, 1)



class OLEDPrinter:
    def __init__(self, oled, line_height=10, max_lines=6, screen_width=128):
        self.oled = oled
        self.line_height = line_height  # 每行文字高度
        self.max_lines = max_lines      # 最多显示的行数
        self.lines = []                 # 存储显示的行
        self.screen_width = screen_width
        self.char_width = 8  # 每个字符占据的宽度 (适用于默认字体)

    def split_text(self, text):
        """将文字按屏幕宽度拆分为多行"""
        max_chars = self.screen_width // self.char_width  # 每行最多字符数
        wrapped_lines = []
        current_line = ""
        for char in text:
            if char in CHINESE_FONT:
                # 中文字符直接占据两字符宽度
                if len(current_line) + 2 > max_chars:
                    wrapped_lines.append(current_line)
                    current_line = ""
                current_line += char
            else:
                # 英文字符占一字符宽度
                if len(current_line) + 1 > max_chars:
                    wrapped_lines.append(current_line)
                    current_line = ""
                current_line += char
        if current_line:
            wrapped_lines.append(current_line)
        return wrapped_lines

    def print(self, *args, sep=' ', end='\n'):
        # 将打印内容转为字符串
        text = sep.join(map(str, args)) + end
        new_line_offset = 0  # 用于标记每一行的偏移量（如果含有中文，偏移量增加8像素）
        for line in text.splitlines():
            # 拆分超长行
            wrapped_lines = self.split_text(line)
            for wrapped_line in wrapped_lines:
                self.lines.append(wrapped_line)
                if len(self.lines) > self.max_lines:  # 超过最大行数，移除顶部一行
                    self.lines.pop(0)

        # 清屏并显示内容
        self.oled.fill(0)  # 清屏
        for i, line in enumerate(self.lines):
            y_offset = i * self.line_height  # 确保y轴偏移量每行增加
            x_offset = 0
            contains_chinese = any(char in CHINESE_FONT for char in line)  # 检查当前行是否包含中文
            for char in line:
                if char in CHINESE_FONT:
                    draw_chinese(self.oled, char, x_offset, y_offset)
                    x_offset += 16  # 中文字符宽度为16
                else:
                    self.oled.text(char, x_offset, y_offset)
                    x_offset += 8  # 英文字符宽度为8
            # 如果当前行包含中文，增加8像素的行间距
            if contains_chinese:
                new_line_offset = 8
            else:
                new_line_offset = 0
            # 将下一行的y_offset增加8像素，避免重叠
            y_offset += new_line_offset

        self.oled.show()

# 定义线程中执行的打印任务
def threaded_print(oled_printer, *args, **kwargs):
    def task():
        oled_printer.print(*args, **kwargs)
    # 使用 _thread 启动新线程
    _thread.start_new_thread(task, ())

def getI2Cstatue():
    # 初始化 I2C 接口
    i2c = I2C(0, scl=Pin(22), sda=Pin(21))  # 根据实际接线调整 Pin 脚
    devices = i2c.scan()
    if devices:
        oled = SSD1306_I2C(128, 64, i2c)  # 宽 128px，高 64px，I2C 地址默认为 0x3C
        return oled
    else:
        print("No I2C devices found")
        return False

if __name__ == "__main__":
    oled = getI2Cstatue()
    if oled:
        oled_printer = OLEDPrinter(oled)
        global print  # 声明 print 为全局变量
        def print(*args, **kwargs):
            threaded_print(oled_printer, *args, **kwargs)
        # 测试中文与英文混排
        print("Hello, 你好!")
        time.sleep(1)
        i = 1
        while True:
            print(f"{i} 你好世界!")
            time.sleep(0.5)
            i += 1
        draw_chinese(oled, "一", 16, 0)
        draw_chinese(oled, "。", 0, 0)
        draw_chinese(oled, "你", 32, 0)
        oled.show()
